[HVM] Clean ups for PV-on-HVM drivers. In particular, platform-pci
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 22 Aug 2006 16:16:58 +0000 (17:16 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 22 Aug 2006 16:16:58 +0000 (17:16 +0100)
driver can now handle multi-page hypercall stub areas.
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
linux-2.6-xen-sparse/include/xen/balloon.h
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
unmodified_drivers/linux-2.6/platform-pci/xen_support.c

index e57924a3f428e9f0cf701f3e36611ae9ff8d1161..f43bf8fe736bf68eb68f61a24095e4c979af713f 100644 (file)
@@ -1577,7 +1577,7 @@ static void xennet_set_features(struct net_device *dev)
        xennet_set_sg(dev, 0);
 
        /* We need checksum offload to enable scatter/gather and TSO. */
-       if (!(dev->features & NETIF_F_ALL_CSUM))
+       if (!(dev->features & NETIF_F_IP_CSUM))
                return;
 
        if (!xennet_set_sg(dev, 1))
index b0324c14a7dc1cf452f680b3d8e1de334c6c3c29..2e6d1fa59693039abbd58e2cbb68344752fa0b47 100644 (file)
 #define __STR(x) #x
 #define STR(x) __STR(x)
 
+#ifdef CONFIG_XEN
+#define HYPERCALL_STR(name)                                    \
+       "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
+#else
+#define HYPERCALL_STR(name)                                    \
+       "mov hypercall_stubs,%%eax; "                           \
+       "add $("STR(__HYPERVISOR_##name)" * 32),%%eax; "        \
+       "call *%%eax"
+#endif
+
 #define _hypercall0(type, name)                        \
 ({                                             \
        long __res;                             \
        asm volatile (                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)             \
                : "=a" (__res)                  \
                :                               \
                : "memory" );                   \
@@ -57,7 +67,7 @@
 ({                                                             \
        long __res, __ign1;                                     \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=b" (__ign1)                   \
                : "1" ((long)(a1))                              \
                : "memory" );                                   \
@@ -68,7 +78,7 @@
 ({                                                             \
        long __res, __ign1, __ign2;                             \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2)    \
                : "1" ((long)(a1)), "2" ((long)(a2))            \
                : "memory" );                                   \
@@ -79,7 +89,7 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
                "=d" (__ign3)                                   \
                : "1" ((long)(a1)), "2" ((long)(a2)),           \
 ({                                                             \
        long __res, __ign1, __ign2, __ign3, __ign4;             \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
                "=d" (__ign3), "=S" (__ign4)                    \
                : "1" ((long)(a1)), "2" ((long)(a2)),           \
 ({                                                             \
        long __res, __ign1, __ign2, __ign3, __ign4, __ign5;     \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
                "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)     \
                : "1" ((long)(a1)), "2" ((long)(a2)),           \
index 753ccb224d348aec73ae9ea9b9e97d8a3e40ab40..14fb01d3d27e02b5bf35d90374094257bf2e46fd 100644 (file)
 #define __STR(x) #x
 #define STR(x) __STR(x)
 
+#ifdef CONFIG_XEN
+#define HYPERCALL_STR(name)                                    \
+       "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
+#else
+#define HYPERCALL_STR(name)                                    \
+       "mov hypercall_stubs,%%rax; "                           \
+       "add $("STR(__HYPERVISOR_##name)" * 32),%%rax; "        \
+       "call *%%rax"
+#endif
+
 #define _hypercall0(type, name)                        \
 ({                                             \
        long __res;                             \
        asm volatile (                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)             \
                : "=a" (__res)                  \
                :                               \
                : "memory" );                   \
@@ -61,7 +71,7 @@
 ({                                                             \
        long __res, __ign1;                                     \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=D" (__ign1)                   \
                : "1" ((long)(a1))                              \
                : "memory" );                                   \
@@ -72,7 +82,7 @@
 ({                                                             \
        long __res, __ign1, __ign2;                             \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2)    \
                : "1" ((long)(a1)), "2" ((long)(a2))            \
                : "memory" );                                   \
@@ -83,7 +93,7 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
                "=d" (__ign3)                                   \
                : "1" ((long)(a1)), "2" ((long)(a2)),           \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
                "movq %7,%%r10; "                               \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
                "=d" (__ign3)                                   \
                : "1" ((long)(a1)), "2" ((long)(a2)),           \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
                "movq %7,%%r10; movq %8,%%r8; "                 \
-               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
+               HYPERCALL_STR(name)                             \
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
                "=d" (__ign3)                                   \
                : "1" ((long)(a1)), "2" ((long)(a2)),           \
index 8d2d32adb17b646f559901c6b97cdd20785e207f..60d7099aa10d8231080bfd93d8bf5e012b4786dd 100644 (file)
  * Inform the balloon driver that it should allow some slop for device-driver
  * memory activities.
  */
-extern void
+void
 balloon_update_driver_allowance(
        long delta);
 
 /* Allocate an empty low-memory page range. */
-extern struct page *
+struct page *
 balloon_alloc_empty_page_range(
        unsigned long nr_pages);
 
 /* Deallocate an empty page range, adding to the balloon. */
-extern void
+void
 balloon_dealloc_empty_page_range(
        struct page *page, unsigned long nr_pages);
 
-void balloon_release_driver_page(struct page *page);
+void
+balloon_release_driver_page(
+       struct page *page);
 
 /*
  * Prevent the balloon driver from changing the memory reservation during
index f32399c3cea5166d54890e56ea534bad167db45c..5d4f25d9c85a03d96e32449a8ada99e914e8cac0 100644 (file)
@@ -39,8 +39,8 @@
 #define DRV_VERSION "0.10"
 #define DRV_RELDATE "03/03/2005"
 
-char hypercall_page[PAGE_SIZE];
-EXPORT_SYMBOL(hypercall_page);
+char *hypercall_stubs;
+EXPORT_SYMBOL(hypercall_stubs);
 
 // Used to be xiaofeng.ling@intel.com
 MODULE_AUTHOR("ssmith@xensource.com");
@@ -116,10 +116,9 @@ unsigned long alloc_xen_mmio(unsigned long len)
 }
 
 /* Lifted from hvmloader.c */
-static int get_hypercall_page(void)
+static int get_hypercall_stubs(void)
 {
-       void *tmp_hypercall_page;
-       uint32_t eax, ebx, ecx, edx;
+       uint32_t eax, ebx, ecx, edx, pages, msr, order, i;
        char signature[13];
 
        cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
@@ -128,9 +127,10 @@ static int get_hypercall_page(void)
        *(uint32_t*)(signature + 8) = edx;
        signature[12] = 0;
 
-       if (strcmp("XenVMMXenVMM", signature) || eax < 0x40000002) {
+       if (strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002)) {
                printk(KERN_WARNING
-                      "Detected Xen platform device but not Xen VMM? (sig %s, eax %x)\n",
+                      "Detected Xen platform device but not Xen VMM?"
+                      " (sig %s, eax %x)\n",
                       signature, eax);
                return -EINVAL;
        }
@@ -139,24 +139,24 @@ static int get_hypercall_page(void)
 
        printk(KERN_INFO "Xen version %d.%d.\n", eax >> 16, eax & 0xffff);
 
-       cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
+       cpuid(0x40000002, &pages, &msr, &ecx, &edx);
 
-       if (eax != 1) {
-               printk(KERN_WARNING
-                      "This Xen version uses a %d page hypercall area,"
-                      "but these modules only support 1 page.\n",
-                      eax);
-               return -EINVAL;
-       }
+       i = pages - 1;
+       for (order = 0; i != 0; order++)
+               i >>= 1;
 
-       tmp_hypercall_page = (void *)__get_free_page(GFP_KERNEL);
-       if (!tmp_hypercall_page)
+       printk(KERN_INFO "Hypercall area is %u pages (order %u allocation)\n",
+              pages, order);
+
+       hypercall_stubs = (void *)__get_free_pages(GFP_KERNEL, order);
+       if (hypercall_stubs == NULL)
                return -ENOMEM;
-       memset(tmp_hypercall_page, 0xcc, PAGE_SIZE);
-       if (wrmsr_safe(ebx, virt_to_phys(tmp_hypercall_page), 0))
-               panic("Can't do wrmsr; not running on Xen?\n");
-       memcpy(hypercall_page, tmp_hypercall_page, PAGE_SIZE);
-       free_page((unsigned long)tmp_hypercall_page);
+
+       for (i = 0; i < pages; i++)
+               wrmsrl(ebx,
+                      virt_to_phys(hypercall_stubs) +  /* base address      */
+                      (i << PAGE_SHIFT) +              /* offset of page @i */
+                      i);                              /* request page @i   */
 
        return 0;
 }
@@ -201,7 +201,7 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
        platform_mmio = mmio_addr;
        platform_mmiolen = mmio_len;
 
-       ret = get_hypercall_page();
+       ret = get_hypercall_stubs();
        if (ret < 0)
                goto out;
 
index c3a6bec595118d935ec1258d6cabb1df6b6f8b8f..b1a903b1c7edc95f6424549cf19693cae89f9fa8 100644 (file)
 #include <asm/hypervisor.h>
 #include "platform-pci.h"
 
-EXPORT_SYMBOL(xen_machphys_update);
 void xen_machphys_update(unsigned long mfn, unsigned long pfn)
 {
        BUG();
 }
+EXPORT_SYMBOL(xen_machphys_update);
 
 void balloon_update_driver_allowance(long delta)
 {
 }
-
 EXPORT_SYMBOL(balloon_update_driver_allowance);
+
+void balloon_release_driver_page(struct page *page)
+{
+}
+EXPORT_SYMBOL(balloon_release_driver_page);